#include <netinet/in.h>
#include <string.h>
#include <zconf.h>
#include "rtp_unit.h"

#ifdef DVSDK_DM3730

void RTPUnit_init(RTPUnit *unit, FILE *file) {
    unit->seq_num = 0;
    unit->ts_current = 3500;
}

//添加客户端 未完成，测试
void RTPUnit_client_add(RTPUnit *unit, int socket_id) {
    unit->socket_id = socket_id;
}

//发送包给客户端 未完成，测试
int RTPUnit_clinent_send(RTPUnit *unit, unsigned char *buf, unsigned int buflen) {
    int ret;
    ret = send(unit->socket_id, buf, buflen, 0);
    return ret;
}


s32_t RTPUnit_pack(RTPUnit *unit, unsigned char *buf, unsigned buflen) {
    s32_t ret;

    u32_t pack_num = 0;     //分包个数
    u32_t pack_byte = 0;    //最后一个包字节数
    u32_t rtp_count = 0;    //包计数

    unit->ts_current += 3600;               //时间戳

    pack_num = (buflen) / RTP_PAYLOAD_MAX_SIZE;
    pack_byte = (buflen) % RTP_PAYLOAD_MAX_SIZE;
    if (pack_byte > 0) pack_num++;

    //输入数据       = [1byte nalu_header] + data
    //不分包输出     = [12byte RTP_header] + [1byte nalu_header] + data
    //分包数据       = [12byte RTP_head] + [1byte Fu_Indicato] + [1byte Fu_Header] + 重复
    RTP_Header *rtp_hdr;
    NALU_Header *nalu_hdr;

    Fu_Indicator *fu_ind;
    Fu_Header *fu_hdr;

    u8_t nalu_head_byte;
    nalu_head_byte = buf[0];

    if (pack_num == 1) {
        //小于分片大小
        rtp_hdr = (RTP_Header *) (unit->buf);
        rtp_hdr->cc = 0;
        rtp_hdr->x = 0;
        rtp_hdr->p = 0;
        rtp_hdr->version = 2;
        rtp_hdr->pt = 96;
        rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
        rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
        rtp_hdr->time = htonl(unit->ts_current);
        rtp_hdr->ssrc = htonl(10);
//        nalu_hdr = (NALU_Header *) (unit + 12);
//        nalu_hdr->f = (nalu_head_byte & 0x80) >> 7;
//        nalu_hdr->nri = (nalu_head_byte & 0x60) >> 5;
//        nalu_hdr->type = (nalu_head_byte & 0x1f);

        memcpy(unit->buf, buf, buflen);
        ret = RTPUnit_clinent_send(unit, unit->buf, buflen + 12);

    } else {
        //头包
        rtp_hdr = (RTP_Header *) (unit->buf);
        rtp_hdr->cc = 0;
        rtp_hdr->x = 0;
        rtp_hdr->p = 0;
        rtp_hdr->version = 2;
        rtp_hdr->pt = 96;
        rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
        rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
        rtp_hdr->time = htonl(unit->ts_current);
        rtp_hdr->ssrc = htonl(10);

        fu_ind = (RTP_Header *) (unit->buf + 12);
        fu_ind->f = (nalu_head_byte & 0x80) >> 7;
        fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
        fu_ind->type = 28;

        fu_hdr = (RTP_Header *) (unit->buf + 13);
        fu_hdr->s = 1;
        fu_hdr->e = 0;
        fu_hdr->r = 0;
        fu_hdr->type = nalu_head_byte & 0x1f;

        memcpy(unit->buf + 14, buf + 1, RTP_PAYLOAD_MAX_SIZE);
        ret = RTPUnit_clinent_send(unit, unit->buf, RTP_PAYLOAD_MAX_SIZE + 14);

        //中间包
        for (rtp_count = 1; rtp_count < pack_num - 1; rtp_count++) {
            rtp_hdr = (RTP_Header *) (unit->buf);
            rtp_hdr->cc = 0;
            rtp_hdr->x = 0;
            rtp_hdr->p = 0;
            rtp_hdr->version = 2;
            rtp_hdr->pt = 96;
            rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
            rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
            rtp_hdr->time = htonl(unit->ts_current);
            rtp_hdr->ssrc = htonl(10);

            fu_ind = (RTP_Header *) (unit->buf + 12);;
            fu_ind->f = (nalu_head_byte & 0x80) >> 7;
            fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
            fu_ind->type = 28;

            fu_hdr = (RTP_Header *) (unit->buf + 13);;
            fu_hdr->s = 0;
            fu_hdr->e = 0;
            fu_hdr->r = 0;
            fu_hdr->type = nalu_head_byte & 0x1f;


            memcpy(unit->buf + 14, rtp_count * RTP_PAYLOAD_MAX_SIZE + 1 + buf, RTP_PAYLOAD_MAX_SIZE);
            ret = RTPUnit_clinent_send(unit, unit->buf, RTP_PAYLOAD_MAX_SIZE + 14);
        }

        //尾包
        if (pack_byte > 0) {
            rtp_hdr = (RTP_Header *) (unit->buf);;
            rtp_hdr->cc = 0;
            rtp_hdr->x = 0;
            rtp_hdr->p = 0;
            rtp_hdr->version = 2;
            rtp_hdr->pt = 96;
            rtp_hdr->m = 1;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
            rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
            rtp_hdr->time = htonl(unit->ts_current);
            rtp_hdr->ssrc = htonl(10);

            fu_ind = (RTP_Header *) (unit->buf + 12);;
            fu_ind->f = (nalu_head_byte & 0x80) >> 7;
            fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
            fu_ind->type = 28;

            fu_hdr = (RTP_Header *) (unit->buf + 13);;
            fu_hdr->s = 0;
            fu_hdr->e = 1;
            fu_hdr->r = 0;
            fu_hdr->type = nalu_head_byte & 0x1f;

            memcpy(unit->buf + 14, rtp_count * RTP_PAYLOAD_MAX_SIZE + 1 + buf, pack_byte);
            ret = RTPUnit_clinent_send(unit, unit->buf, pack_byte + 14);
        }
    }
    return ret;
}

#else

void RTPUnit_init(RTPUnit *unit, RTSPService *service, FILE *file) {
    RLBufFile_init(&unit->bfile, file, unit->filebuf, RTP_FILE_BUF_SIZE);   //初始化读取缓冲区
    PBufArray_init(&unit->pbbuf, unit->framebuf + RTP_FRAME_HEADER_SIZE, RTP_FRAME_BUF_SIZE + RTP_FRAME_HEADER_SIZE);
    unit->seq_num = 0;
    unit->ts_current = 3600;
    unit->service = service;
    TWList_init(&unit->cliten_list);
}

//添加客户端 未完成，测试
int RTPUnit_client_add(RTPUnit *unit, TWListNode *node) {
    TWList_insert_node(&unit->cliten_list, node);
}

//添加客户端 未完成，测试
int RTPUnit_client_delete(RTPUnit *unit, TWListNode *node) {
    if (node == 0)
        return 0;
    TWList_delete_node(&unit->cliten_list, node);
    return 0;
}

//发送包给客户端 未完成，测试
int RTPUnit_clinent_send(RTPUnit *unit, unsigned char *buf, unsigned int buflen) {
    int ret = 0;
    TWListNode *node;
    RTPUser *user;
    node = unit->cliten_list.headptr;
    while (node != 0) {
        user = node->dataptr;
        if (user->type == RTPUSER_TYPE_UDP) {
            ret = sendto(user->send_socket, buf, buflen, 0, (struct sockaddr *) &user->c_rtp_in,
                         sizeof(struct sockaddr));
//            Debug("发送RTP数据 %d\n", ret);
        } else {
            ret = send(user->send_socket, buf, buflen, 0);
        }

        node = node->nextptr;
    }
//    for (int i = 0; i < buflen; i++) {
//        if (i > buflen - 10 || i < 20)
//            printf("%x ", buf[i]);
//    }
//    printf("  -- %d\n", buflen);
    return ret;
}


//*从文件读取一帧数据
int RTPUnit_frame_read(RTPUnit *unit) {
    unsigned char ch;
    s32_t ret;
    u32_t flag = 0;
//    RLBufFile *in = ;
    PBufArray *out = &unit->pbbuf;
    while (1) {
        //从文件中读取一个字节
        ret = RLBufFile_read_byte(&unit->bfile, &ch);
        if (ret != RLBUFFILE_RET_SUCCEED) {
            if (ret == RLBUFFILE_RET_EOF)
                ret = RTSPUNIT_RET_SUCCEED;
            return ret;
        }
        switch (flag) {
            case 0://判断第一个字节
                if (ch == 0) {
                    flag = 1;
                } else {
                    PBufArray_wirite_byte(out, ch);
                }
                break;
            case 1://判断第二字节
                if (ch == 0) {
                    flag = 2;
                } else {
                    flag = 0;
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, ch);
                }
                break;
            case 2://判断第三字节
                if (ch == 0) {
                    flag = 3;
                } else if (ch == 1) {
                    if (out->w_idx != 0) {
                        return RTPUNIT_RET_SUCCEED;
                    } else {
                        flag = 0;
                    }
                } else {
                    flag = 0;
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, ch);
                }
                break;
            case 3://判断第四字节
                if (ch == 1) {
                    if (out->w_idx != 0) {
                        return RTPUNIT_RET_SUCCEED;
                    } else {
                        flag = 0;
                    }
                } else {
                    flag = 0;
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, 0);
                    PBufArray_wirite_byte(out, ch);
                }
                break;
            default:
                break;
        }

    }
    return ret;
}

s32_t RTPUnit_pack_send(RTPUnit *unit) {
    s32_t ret;

    u32_t pack_num = 0;     //分包个数
    u32_t pack_byte = 0;    //最后一个包字节数
    u32_t rtp_count = 0;    //包计数


    unit->ts_current += 3600;               //时间戳

    pack_num = (unit->pbbuf.w_idx) / RTP_PAYLOAD_MAX_SIZE;
    pack_byte = (unit->pbbuf.w_idx) % RTP_PAYLOAD_MAX_SIZE;
    if (pack_byte > 0) pack_num++;

    RTP_Header *rtp_hdr;
    NALU_Header *nalu_hdr;

    Fu_Indicator *fu_ind;
    Fu_Header *fu_hdr;

    u8_t nalu_head_byte;
    nalu_head_byte = unit->framebuf[RTP_FRAME_HEADER_SIZE];

    if (pack_num == 1) {
        //小于分片大小
        rtp_hdr = (RTP_Header *) (unit->framebuf + RTP_FRAME_HEADER_SIZE - 12);
        rtp_hdr->cc = 0;
        rtp_hdr->x = 0;
        rtp_hdr->p = 0;
        rtp_hdr->version = 2;
        rtp_hdr->pt = 96;
        rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
        rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
        rtp_hdr->time = htonl(unit->ts_current);
        rtp_hdr->ssrc = htonl(10);

        nalu_hdr = (NALU_Header *) (unit->framebuf);
        nalu_hdr->f = (nalu_head_byte & 0x80) >> 7;
        nalu_hdr->nri = (nalu_head_byte & 0x60) >> 5;
        nalu_hdr->type = (nalu_head_byte & 0x1f);

        ret = RTPUnit_clinent_send(unit, unit->framebuf + 1, unit->pbbuf.w_idx + 12);

    } else {
        //头包
        rtp_hdr = (RTP_Header *) (unit->framebuf + RTP_FRAME_HEADER_SIZE - 13);
        rtp_hdr->cc = 0;
        rtp_hdr->x = 0;
        rtp_hdr->p = 0;
        rtp_hdr->version = 2;
        rtp_hdr->pt = 96;
        rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
        rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
        rtp_hdr->time = htonl(unit->ts_current);
        rtp_hdr->ssrc = htonl(10);

        fu_ind = (Fu_Indicator *) (unit->framebuf + RTP_FRAME_HEADER_SIZE - 1);
        fu_ind->f = (nalu_head_byte & 0x80) >> 7;
        fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
        fu_ind->type = 28;

        fu_hdr = (Fu_Header *) (unit->framebuf + RTP_FRAME_HEADER_SIZE);
        fu_hdr->s = 1;
        fu_hdr->e = 0;
        fu_hdr->r = 0;
        fu_hdr->type = nalu_head_byte & 0x1f;
        ret = RTPUnit_clinent_send(unit, unit->framebuf + RTP_FRAME_HEADER_SIZE - 13, RTP_PAYLOAD_MAX_SIZE + 13);

        //中间包
        for (rtp_count = 1; rtp_count < pack_num - 1; rtp_count++) {
            rtp_hdr = (RTP_Header *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 14);
            rtp_hdr->cc = 0;
            rtp_hdr->x = 0;
            rtp_hdr->p = 0;
            rtp_hdr->version = 2;
            rtp_hdr->pt = 96;
            rtp_hdr->m = 0;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
            rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
            rtp_hdr->time = htonl(unit->ts_current);
            rtp_hdr->ssrc = htonl(10);

            fu_ind = (Fu_Indicator *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 2);;
            fu_ind->f = (nalu_head_byte & 0x80) >> 7;
            fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
            fu_ind->type = 28;

            fu_hdr = (Fu_Header *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 1);;
            fu_hdr->s = 0;
            fu_hdr->e = 0;
            fu_hdr->r = 0;
            fu_hdr->type = nalu_head_byte & 0x1f;
            ret = RTPUnit_clinent_send(unit,
                                       RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 14,
                                       RTP_PAYLOAD_MAX_SIZE + 14);
        }

        //尾包
        if (pack_byte > 0) {
            rtp_hdr = (RTP_Header *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 14);;
            rtp_hdr->cc = 0;
            rtp_hdr->x = 0;
            rtp_hdr->p = 0;
            rtp_hdr->version = 2;
            rtp_hdr->pt = 96;
            rtp_hdr->m = 1;    /* 该包为一帧的结尾则置为1, 否则为0. rfc 1889 没有规定该位的用途 */
            rtp_hdr->seq = htons(++unit->seq_num % UINT16_MAX);
            rtp_hdr->time = htonl(unit->ts_current);
            rtp_hdr->ssrc = htonl(10);

            fu_ind = (Fu_Indicator *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 2);;
            fu_ind->f = (nalu_head_byte & 0x80) >> 7;
            fu_ind->nri = (nalu_head_byte & 0x60) >> 5;
            fu_ind->type = 28;

            fu_hdr = (Fu_Header *) (RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 1);;
            fu_hdr->s = 0;
            fu_hdr->e = 1;
            fu_hdr->r = 0;
            fu_hdr->type = nalu_head_byte & 0x1f;
            ret = RTPUnit_clinent_send(unit,
                                       RTP_PAYLOAD_MAX_SIZE * rtp_count + unit->framebuf + RTP_FRAME_HEADER_SIZE - 14,
                                       pack_byte + 14);
        }
    }
    return ret;
}


void *RTPUnit_send_task(RTPUnit *unit) {
    int ret;
    //判断是否有连接
    ret = RTPUnit_frame_read(unit);
    if (ret == RTSPUNIT_RET_SUCCEED) {
        RTPUnit_pack_send(unit);
        PBufArray_reset(&unit->pbbuf);
        usleep(1000*30);
    }
    return 0;
}

#endif